from alibabacloud_green20220302.client import Client
from alibabacloud_green20220302 import models
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.client import Client as UtilClient
from alibabacloud_tea_util import models as util_models
import json
import uuid
import oss2
import time
import requests
import json
from setting import *
# 服务是否部署在vpc上
is_vpc = False
# 文件上传token endpoint->token
token_dict = dict()
# 上传文件客户端
bucket = None

#下载图片
def download_image(image_url, save_dir="images", filename=None):
    """
    从指定URL下载图片并保存到本地
    
    参数:
    image_url (str): 图片的URL地址
    save_dir (str): 保存图片的目录，默认为当前目录下的"images"文件夹
    filename (str): 自定义文件名（可选），不包含扩展名
    
    返回:
    str: 保存的文件路径，如果下载失败则返回None
    """
    try:
        # 1. 创建保存目录
        os.makedirs(save_dir, exist_ok=True)
        
        # 2. 发送HTTP请求获取图片
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
        }
        response = requests.get(image_url, headers=headers, stream=True, timeout=10)
        response.raise_for_status()  # 检查HTTP错误
        
        # 3. 确定文件名
        if filename is None:
            # 从URL提取文件名
            parsed_url = urlparse(image_url)
            original_filename = Path(parsed_url.path).name
            
            # 从Content-Disposition获取文件名（如果有）
            content_disposition = response.headers.get("Content-Disposition", "")
            if "filename=" in content_disposition:
                original_filename = content_disposition.split("filename=")[-1].strip('"')
            
            # 生成安全的文件名
            safe_filename = "".join(c for c in original_filename if c.isalnum() or c in ('_', '-', '.'))
            filename_base = safe_filename.split('.')[0] or "image"
        else:
            filename_base = filename
        
        # 4. 确定文件扩展名
        # 优先从Content-Type获取
        content_type = response.headers.get("Content-Type", "").lower()
        if content_type.startswith("image/"):
            extension = content_type.split("/")[1]
        else:
            # 从URL获取扩展名
            extension = Path(parsed_url.path).suffix[1:] or "jpg"
        
        # 5. 构建保存路径
        save_path = os.path.join(save_dir, f"{filename_base}.{extension}")
        
        # 避免覆盖已有文件
        counter = 1
        while os.path.exists(save_path):
            save_path = os.path.join(save_dir, f"{filename_base}_{counter}.{extension}")
            counter += 1
        
        # 6. 保存图片
        with open(save_path, "wb") as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)
        
        print(f"✅ 图片已成功保存到: {save_path}")
        return save_path
        
    except requests.exceptions.RequestException as e:
        print(f"❌ 下载失败: {e}")
        return None
    except Exception as e:
        print(f"❌ 发生错误: {e}")
        return None
# 结果转换
def normalize_response(api_response):
    """
    将API响应转换为标准化的图片检测结果
    
    参数:
        api_response: 图片检测API返回的原始响应
        
    返回:
        标准化的结果字典
    """
    # 映射风险等级到建议
    risk_to_suggestion = {
        'none': 'pass',
        'low': 'review',
        'medium': 'review',
        'high': 'block',
        'review': 'review',
        'block': 'block'
    }
    
    # 提取主要标签
    primary_label = api_response['Result'][0]['Label'] if api_response.get('Result') else 'unknown'
    
    return {
        'status': 200,  # 假设所有成功响应都是200
        'suggestion': risk_to_suggestion.get(api_response.get('RiskLevel', 'none'), 'review'),
        'label': primary_label,
        'confidence': 1.0 if api_response['RiskLevel'] == 'none' else 0.0,  # 无风险则置信度1.0
        'details': {
            'api_response': api_response,  # 保留原始响应
            'risk_interpretation': {
                'none': "无风险内容",
                'low': "低风险内容",
                'medium': "中风险内容",
                'high': "高风险内容"
            }.get(api_response['RiskLevel'], "未知风险级别")
        }
    }


def imageCheck(image_path):
    access_key_id=ALIYUN_ACCESS_KEY_ID
    access_key_secret=ALIYUN_ACCESS_KEY_SECRET
    
    try:
        # 接入区域和地址请根据实际情况修改。
        response = invoke_function(image_path,access_key_id, access_key_secret, 'green-cip.cn-shanghai.aliyuncs.com')
        if response is not None:
            if UtilClient.equal_number(500,
                                       response.status_code) or (response.body is not None and 200 != response.body.code):
                # 区域切换到cn-beijing。
                response = invoke_function(image_path,access_key_id, access_key_secret, 'green-cip.cn-beijing.aliyuncs.com')

            if response.status_code == 200:
                # 获取审核结果。
                result = response.body
                if result.code == 200:
                    data = result.data
                    result_list = []
                    for res in data.result:
                        result_list.append({
                            'Description': res.description,
                            'Label': res.label
                        })
                    api_response = {
                        'DataId': data.data_id,
                        'Result': result_list,
                        'RiskLevel': data.risk_level
                    }

                    return normalize_response(api_response)


            else:
                # 错误处理
                return {
                    'status': 500,
                    'suggestion': 'error',
                    'label': 'api_error',
                    'confidence': 0.0,
                    'details': {
                        'error_type': type(e).__name__,
                        'error_message': str(e)
                    }
                }



    except Exception as e:
        # 错误处理
        return {
            'status': 500,
            'suggestion': 'error',
            'label': 'api_error',
            'confidence': 0.0,
            'details': {
                'error_type': type(e).__name__,
                'error_message': str(e)
            }
        }

# 创建请求客户端
def create_client(access_key_id, access_key_secret, endpoint):
    config = Config(
        access_key_id=access_key_id,
        access_key_secret=access_key_secret,
        # 设置http代理。
        # http_proxy='http://10.10.xx.xx:xxxx',
        # 设置https代理。
        # https_proxy='https://10.10.xx.xx:xxxx',
        # 接入区域和地址请根据实际情况修改。
        endpoint=endpoint
    )
    return Client(config)


# 创建文件上传客户端
def create_oss_bucket(is_vpc, upload_token):
    global token_dict
    global bucket
    auth = oss2.StsAuth(upload_token.access_key_id, upload_token.access_key_secret, upload_token.security_token)

    if (is_vpc):
        end_point = upload_token.oss_internal_end_point
    else:
        end_point = upload_token.oss_internet_end_point
    # 注意：此处实例化的bucket请尽可能重复使用，避免重复建立连接，提升检测性能。
    bucket = oss2.Bucket(auth, end_point, upload_token.bucket_name)

# 上传文件
def upload_file(file_name, upload_token):
    create_oss_bucket(is_vpc, upload_token)
    object_name = upload_token.file_name_prefix + str(uuid.uuid1()) + '.' + file_name.split('.')[-1]
    bucket.put_object_from_file(object_name, file_name)
    return object_name


def invoke_function(file_path,access_key_id, access_key_secret, endpoint):
    # 注意：此处实例化的client请尽可能重复使用，避免重复建立连接，提升检测性能。
    client = create_client(access_key_id, access_key_secret, endpoint)
    # 创建RuntimeObject实例并设置运行参数。
    runtime = util_models.RuntimeOptions()

    # 本地文件的完整路径，例如D:\localPath\exampleFile.png
  

    # 获取文件上传token
    upload_token = token_dict.setdefault(endpoint, None)
    if (upload_token == None) or int(upload_token.expiration) <= int(time.time()):
        response = client.describe_upload_token()
        upload_token = response.body.data
        token_dict[endpoint] = upload_token
    # 上传文件
    object_name = upload_file(file_path, upload_token)

    # 检测参数构造。
    service_parameters = {
        # 待检测文件所在bucket名称。
        'ossBucketName': upload_token.bucket_name,
        # 待检测文件。
        'ossObjectName': object_name,
        # 数据唯一标识
        'dataId': str(uuid.uuid1())
    }

    image_moderation_request = models.ImageModerationRequest(
        # 图片检测service：内容安全控制台图片增强版规则配置的serviceCode，示例：baselineCheck
        # 支持service请参考：https://help.aliyun.com/document_detail/467826.html?0#p-23b-o19-gff
        service='postImageCheck',
        service_parameters=json.dumps(service_parameters)
    )

    try:
        return client.image_moderation_with_options(image_moderation_request, runtime)
    except Exception as err:
        print(err)


if __name__ == '__main__':
    image_path = 'C:\\Users\\rmk\\Desktop\\1.png'
    imageCheck_rs=imageCheck(image_path)
    print(imageCheck_rs)
    
